
import stepment from "./stepment";
import {LGXEnums}  from "./../../common/sysenum.js";


import globalConst from '../../common/globalConst.js'
var global = globalConst.GlobalConst;

import UtilFuncs from "../../common/tools/utilfuncs";
var utilfuncs = UtilFuncs.UtilFuncs;

let MAXRECORD = 500;

class ActionTaker {
    constructor(datamanger) {
        this.m_tRelateRes = new Array();
        this.m_tRelateGph = new Array();
        this.m_pDataManager = datamanger;
        this.m_tMemList = new Array();
        this.m_nIterator = -1;
        this.m_nState = -1;
    }

    remember(startFlag) {
        let nCount = this.m_tMemList.length;
        var tGraphNew = new Array();
        var tResNew = new Array();

        if ((this.m_nState == 1) && (startFlag)) {
            if (nCount >= 1) {
                let pMemStart = this.m_tMemList[nCount - 1];
                if (pMemStart.m_nStart == 1) {
                    this.m_tMemList.splice(nCount - 1,1);
                    if (nCount > 1) {
                        this.m_nIterator = nCount - 2;
                        this.m_nState = 0;
                    }
                    else {
                        this.m_nIterator = -1;
                        this.m_nState = -1;
                    }
                }
            }
        }
        else if ((this.m_nState == 0) && (startFlag == 0)) {
            if (nCount >= 1) {
                let pMemStart = this.m_tMemList[nCount - 1];
                if (pMemStart.m_nStart == 0) {
                    this.copyNewInfo(pMemStart, tGraphNew, tResNew);
                    this.m_tMemList.splice(nCount - 1,1);
                    if (nCount > 1) {
                        this.m_nIterator = nCount - 2;
                    }
                    else {
                        this.m_nIterator = -1;
                    }

                    if (nCount > 1) {
                        this.m_nIterator = nCount - 2;
                        this.m_nState = 0;
                    }
                    else {
                        this.m_nIterator = -1;
                        this.m_nState = -1;
                    }
                }
            }
        }

        if (this.m_nState == 1) {
            if (this.m_nIterator <= nCount - 2) {
                let i = nCount - 2;
                while (i >= this.m_nIterator) {
                    let pMemStart = this.m_tMemList[i];
                    let pMemEnd = this.m_tMemList[i + 1];
                    if ((pMemStart.m_nStart == 1) &&
                        (pMemEnd.m_nStart == 0)) {
                        this.m_tMemList.splice(i + 1,1);
                        this.m_tMemList.splice(i,1);
                    }
                    i -= 2;
                }

                nCount = this.m_tMemList.length;
                if (this.m_nIterator > nCount - 1) {
                    this.m_nIterator = nCount - 1;
                }
                this.m_nState = 0;
            }
        }
        else if (this.m_nState == 0) {
            if (this.m_nIterator < nCount - 2) {
                let i = nCount - 2;
                while (i > this.m_nIterator) {
                    let pMemStart = this.m_tMemList[i];
                    let pMemEnd = this.m_tMemList[i + 1];
                    if ((pMemStart.m_nStart == 1) &&
                        (pMemEnd.m_nStart == 0)) {
                        this.m_tMemList.splice(i + 1,1);
                        this.m_tMemList.splice(i,1);
                    }

                    i -= 2;
                }

                nCount = this.m_tMemList.length;
                if (this.m_nIterator > nCount - 1) {
                    this.m_nIterator = nCount - 1;
                }
            }
        }

        if (this.m_nIterator == MAXRECORD) {
            this.m_tMemList.splice(0,1);
            this.m_nIterator--;
        }

        this.m_nState = startFlag;

        var pMem = new stepment.StepMent();
        pMem.m_nStart = startFlag;

        nCount = this.m_tRelateGph.length;
        for (let j = 0; j < nCount; j++) {
            let pGraph = this.m_tRelateGph[j];
            let pGraphUnit = pGraph.toInfo();
            if (pGraphUnit){
                pMem.m_tGraphMem.push(pGraphUnit);
            }
            if (startFlag == 0){
                pGraph.setModifing(0);
            }
        }

        nCount = this.m_tRelateRes.length;
        for (let h = 0; h < nCount; h++) {
            let pResource = this.m_tRelateRes.at(h);
            let pResUnit = pResource.toInfo();
            if (pResUnit)
                pMem.m_tResMem.push(pResUnit);
        }

        this.m_nIterator++;
        this.m_tMemList.push(pMem);
        this.pasteNewInfo(pMem, tGraphNew, tResNew);
        return 0;
    }

    forward() {
        let nRst = 0;
        if (this.m_nState != 0) {
            if (this.m_nIterator > this.m_tMemList.length - 2) {
                return -1;
            }
            this.m_nIterator++;
            nRst = this.resume();
        }
        else {
            if (this.m_nIterator > this.m_tMemList.length - 3) {
                return -1;
            }

            this.m_nIterator += 2;
            nRst = this.resume();
        }

        this.m_nState = 0;
        return nRst;
    }
    backward() {
        let nRst = 0;
        var tNewGraphLst = new Array();
        var tNewResLst = new Array();
        if (this.m_nState != 0) {
            if (this.m_nIterator - 2 < 0) {
                return -1;
            }

            this.m_nIterator--;
            this.getNewGraphAndRes(tNewGraphLst, tNewResLst);

            this.m_nIterator--;
            nRst = this.resume();
        }
        else {
            if (this.m_nIterator - 1 < 0) {
                return -1;
            }
            this.getNewGraphAndRes(tNewGraphLst, tNewResLst);
            this.m_nIterator--;
            nRst = this.resume();
        }
        this.m_nState = 1;
        //撤销时隐藏本步骤产生的所有新图形、新电气资源数据
        this.hideNewDatas(tNewGraphLst, tNewResLst);
        return nRst;
    }

    //撤销时隐藏本步骤产生的所有新图形、新电气资源数据
    hideNewDatas(tNewGraphLst, tNewResLst) {
        for (let i = 0; i < tNewGraphLst.length; i++) {
            let pGraph = tNewGraphLst[i];
            pGraph.setUseful(0);
            if (pGraph == this.m_pDataManager.getCurentGraph()) {
                this.m_pDataManager.setCurentGraph(null);
            }
        }

        for (let i = 0; i < tNewResLst.length; i++) {
            let pResource = tNewResLst[i];
            pResource.setUseful(0);
            let resType = utilfuncs.mainObjType(pResource.gid);
            if (resType == global.ConnectLine) {
                pLineSeg.clearNode();
            }
            else if (resType == global.TopoNode) {
                pNode.clearConnLineSeg();
            }
        }
    }

    getNewGraphAndRes(tNewGraphLst, tNewResLst) {
        if ((this.m_nIterator < 0) || (this.m_nIterator >= this.m_tMemList.length)) {
            return 1;
        }

        let pMem = this.m_tMemList[this.m_nIterator];
        for (let i = 0; i < pMem.m_tGraphMem.length; i++) {
            let pGphMem = pMem.m_tGraphMem[i];
            if (pGphMem.m_nNewAdd == 1) {
                let pGraph = this.m_pDataManager.findGraph(pGphMem.gid);
                if (pGraph) {
                    tNewGraphLst.push(pGraph);
                }
            }
        }

        let managePowerRes = this.m_pDataManager.getTopoManager();
        for (let i = 0; i < pMem.m_tResMem.length; i++) {
            let pResMem = pMem.m_tResMem[i];
            if (pResMem.m_nNewAdd == 1) {
                let pResource = managePowerRes.findResource(pResMem.rid);
                if (pResource) {
                    tNewResLst.push(pResource);
                }
            }
        }
        return 0;
    }

    pasteNewInfo(pMem, tGraphNew, tResNew) {
        let nGraph = pMem.m_tGraphMem.length;
        for (let i = 0; i < nGraph; i++) {
            let pGraphMem = pMem.m_tGraphMem[i];
            let nIN = tGraphNew.indexOf(pGraphMem.gid);
            if (nIN >= 0) {
                pGraphMem.m_nNewAdd = 1;
            }
        }

        let nRes = pMem.m_tResMem.length;
        for (let j = 0; j < nRes; j++) {
            let pResMem = pMem.m_tResMem.at(j);
            let nIN = tResNew.indexOf(pResMem.gid);
            if (nIN >= 0) {
                pResMem.m_nNewAdd = 1;
            }
        }
        return 0;
    }

    recover(pGraph) {
        if (this.m_nState == 0) {
            return 1;
        }

        let ret = this.resume();
        this.m_tMemList.splice(m_nIterator,1);
        this.m_nIterator--;
        return ret;
    }

    resume() {
        let nMemCount = this.m_tMemList.length;
        if ((this.m_nIterator < 0) && (this.m_nIterator >= nMemCount) && (nMemCount <= 0)) {
            return 1;
        }

        let failed = 0;
        let pMem = this.m_tMemList[this.m_nIterator];
        let nCount = pMem.m_tGraphMem.length;
        for (let j = 0; j < nCount; j++) {
            let pGphUnit = pMem.m_tGraphMem[j];
            failed = this.resumeGraph(pGphUnit);
        }

        nCount = pMem.m_tResMem.length;
        for (let j = 0; j < nCount; j++) {
            let pResUnit = pMem.m_tResMem[j];
            failed = this.resumeTopoResData(pResUnit);
        }
        return failed;
    }


    resumeGraph(pGphUnit) {
        let pGraph = this.m_pDataManager.findGraph(pGphUnit.gid);
        if (!pGraph) {
            return 0;
        }

        let mapscale = this.m_pDataManager.getMapScale();
        this.m_pDataManager.recordRepaintScope(pGraph);
        pGraph.modifyAttribute(pGphUnit, mapscale);
        this.m_pDataManager.recordRepaintScope(pGraph);

        if (pGphUnit.superID) {
            let pSupGraph = this.m_pDataManager.findGraph(pGphUnit.superID);
            if (pSupGraph) {
                pSupGraph.addChild(pGraph);
            }
        }

        return 0;
    }

    resumeTopoResData(pResUnit) {
        let managePowerRes = this.m_pDataManager.getTopoManager();
        let pResource = managePowerRes.findResource(pResUnit.id);
        if (pResource) {
            this.copyMemInfoToResource(pResUnit, pResource);
        }
        return 0;
    }

    copyMemInfoToResource(pResUnit, pDstResource) {
        switch(pDstResource.type){
            case "connline":
            case "conduct":
            break;

        case "node":
            this.copyMemNode2DstNode(pResUnit, pDstResource);
            break;
        }
    }

    copyMemNode2DstNode(pNodeUnit, pDstNode){
        pDstNode.setPos(pNodeUnit.x,pNodeUnit.y);
    }

    getChangeGraph(nCommand, tGraphs) {
        if ((this.m_nIterator < 0) || (this.m_nIterator >= this.m_tMemList.length)) {
            return 1;
        }

        let nRect = 0;
        let nIndex = 0;
        if (nCommand == 1)//回退
        {
            if (this.m_nState != 0) {
                if (this.m_nIterator > this.m_tMemList.length - 2) {
                    return 1;
                }
                nIndex = this.m_nIterator + 1;
            }
            else {
                if (this.m_nIterator > this.m_tMemList.length - 3) {
                    return 1;
                }
                nIndex = this.m_nIterator + 2;
            }

            let pMem = this.m_tMemList[nIndex];
            let nGraph = pMem.m_tGraphMem.length;
            for (let i = 0; i < nGraph; i++) {
                let pGphMem = pMem.m_tGraphMem[i];
                let pGraph = this.m_pDataManager.findGraph(pGphMem.gid);
                if (pGraph) {
                    if (pGraph.m_graphType == LGXEnums.LGXGraphType.MultiSel_Rect_Type) {
                        nRect = 1;
                    }
                    tGraphs.push(pGraph);
                }
            }
        }  // 1 ------------------- //回退结束
        else if (nCommand == 2)  // ------------------开始撤销
        {
            if (this.m_nState != 0) {
                if (this.m_nIterator - 2 < 0) {
                    return 1;
                }
                nIndex = this.m_nIterator - 2;
            }
            else {
                if (this.m_nIterator - 1 < 0) {
                    return 1;
                }
                nIndex = this.m_nIterator - 1;
            }

            var pMem = this.m_tMemList[nIndex];
            let nGraph = pMem.m_tGraphMem.length;
            for (let i = 0; i < nGraph; i++) {
                let pGphMem = pMem.m_tGraphMem[i];
                let pGraph = this.m_pDataManager.findGraph(pGphMem.gid);
                if (pGraph) {
                    if (pGraph.m_graphType == LGXEnums.LGXGraphType.MultiSel_Rect_Type) {
                        nRect = 1;
                    }
                    tGraphs.push(pGraph);
                }
            }

            pMem = this.m_tMemList[nIndex + 1];
            nGraph = pMem.m_tGraphMem.length;
            for (let j = 0; j < nGraph; j++) {
                let pGphMem = pMem.m_tGraphMem[j];
                if (pGphMem.m_nNewAdd != 0) {
                    let pGraph = this.m_pDataManager.findGraph(pGphMem.gid);
                    if (pGraph) {
                        tGraphs.push(pGraph);
                    }
                }
            }
        }  // 2 ------------------- //撤销结束
        return 0;
    }

    removePreStep() {
        if (this.m_nState <= 0) {
            return -1;
        }
        let nMemCount = this.m_tMemList.length;
        if (nMemCount < 1) {
            return -1;
        }
        if ((this.m_nIterator < 0) && (this.m_nIterator >= nMemCount) && (nMemCount <= 0)) {
            return -1;
        }

        this.m_nIterator--;
        let pMem = this.m_tMemList[nMemCount - 1];
        pMem.m_tGraphMem.length = 0;
        pMem.m_tResMem.length = 0;
        this.m_tMemList.splice(nMemCount - 1, 1);
        this.m_nState = 0;
        return 0;
    }

    copyNewInfo(pMem, tGraphNew, tResNew) {
        let nGraph = pMem.m_tGraphMem.length;
        for (let i = 0; i < nGraph; i++) {
            let pGraphMem = pMem.m_tGraphMem[i];
            if (pGraphMem.m_nNewAdd == 1) {
                tGraphNew.push(pGraphMem.gid);
            }
        }

        let nRes = pMem.m_tResMem.length;
        for (let j = 0; j < nRes; j++) {
            let pResMem = pMem.m_tResMem[j];
            if (pResMem.m_nNewAdd == 1) {
                tResNew.push(pResMem.gid);
            }
        }

        return 0;
    }

    clearRelate() {
        this.m_tRelateGph.length = 0;
        this.m_tRelateRes.length = 0;
    }
    addRelateGraph(graph) {
        if (graph && this.m_tRelateGph.indexOf(graph) == -1) {
            this.m_tRelateGph.push(graph);
        }
    }

    addRelateRes(topoRes) {
        if (!topoRes) {
            return ;
        }
        this.add2List(topoRes);
        if (topoRes.type == "conduct" || topoRes.type == "connline"){
            let connNodeList = topoRes.getConnNodeList();
            for (let i = 0; i < connNodeList.length; i++) {
                let node = connNodeList[i];
                this.add2List(node);
            }
        }
    }

    add2List(resource) {
        if (resource && this.m_tRelateRes.indexOf(resource) == -1) {
            this.m_tRelateRes.push(resource);
        }
    }

    getRelateGraphLst() { return this.m_tRelateGph; }
}

export default { ActionTaker }